MOOC Utils

Utils like auto assignment solver extension and course notice announcment notification for MOOC courses

Announcement tracking

Introduction#

How announcements are scraped, stored, and surfaced for subscribed courses.

What works today

  • Course search and announcement fetch via Swayam
  • Announcement cache with dedupe and content updates
  • User subscriptions
  • Notification history
  • REST API for authenticated users

Still on the roadmap: Telegram and email for real-time alerts.

Project structure#

The announcement tracking system resides in the notice-reminders package under app/. The structure separates concerns into:

  • Core: configuration, database initialization, and dependency injection
  • Services: business logic for announcements, courses, subscriptions, and notifications
  • Models: Tortoise ORM entities for persistence
  • Schemas: Pydantic models for API serialization
  • API Routers: FastAPI endpoints for announcements, subscriptions, notifications, and users
  • Scrapers: Integration with Swayam scraping utilities

Core components#

  • AnnouncementService: Orchestrates fetching announcements from SwayamService, deduplicating by course/title/date, updating content if changed, and storing via Tortoise ORM.
  • SwayamService: Wraps the Swayam scraping integration and exposes asynchronous methods to search courses and fetch announcements.
  • CourseService: Manages course metadata and retrieval by code.
  • NotificationService: Tracks notification events linked to users, subscriptions, and announcements; supports listing notification history.
  • SubscriptionService: Manages user-course subscriptions with activation controls.
  • NotificationChannelService: Manages user notification channels (e.g., Telegram, Email) for future alert delivery.
  • Models: Define the relational schema for announcements, courses, subscriptions, notifications, and notification channels.
  • Schemas: Define API response models for announcements and other entities.

Key responsibilities:

  • Automated monitoring: AnnouncementService periodically triggers SwayamService to fetch announcements for subscribed courses.
  • Parsing and caching: Deduplication and content update logic prevent redundant writes and keep cached content fresh.
  • Real-time alert readiness: NotificationService and NotificationChannelService provide the foundation for dispatching alerts when new announcements are detected.

Architecture overview#

The system follows a layered architecture:

  • Presentation Layer: FastAPI routers expose endpoints for announcements, subscriptions, notifications, and users.
  • Application Layer: Services encapsulate business logic for announcements, courses, subscriptions, and notifications.
  • Persistence Layer: Tortoise ORM models define the schema and relationships.
  • Integration Layer: SwayamService integrates with scraping utilities to fetch course announcements.

Detailed component analysis#

Announcement data model#

The Announcement entity stores parsed course announcements with a foreign key to Course. It includes fields for title, date, content, and timestamps for caching and sorting.

Announcement parsing and caching workflow#

The AnnouncementService fetches announcements from SwayamService, deduplicates by course, title, and date, and updates content if changed. It keeps efficient caching and avoids redundant database writes.

Notification history and triggering logic#

Notifications link users, subscriptions, and announcements. The Notification entity optionally links to a NotificationChannel for delivery. The NotificationService provides listing of notification history for a user or subscription.

API endpoints for announcements, subscriptions, and notifications#

  • GET /courses/{course_code}/announcements

  • Purpose: Retrieve and cache announcements for a course

  • Authentication: Required

  • Response: List of AnnouncementResponse

  • Implementation: announcements.py

  • GET /users/{user_id}/subscriptions

  • Purpose: List a user’s course subscriptions

  • Authentication: Required

  • Response: List of SubscriptionResponse

  • Implementation: subscriptions.py

  • GET /users/{user_id}/notifications

  • Purpose: List notification history for a user

  • Authentication: Required

  • Response: List of NotificationResponse

  • Implementation: notifications.py

  • GET /users/me

  • Purpose: Get current user profile

  • Authentication: Required

  • Response: UserResponse

  • Implementation: users.py

Note: The endpoints above reflect the current API surface. Additional endpoints for managing subscriptions and notifications are defined in their respective routers.

Scheduling and caching strategies#

  • Cache TTL: Controlled by Settings.cache_ttl_minutes, which determines how frequently announcements are refreshed.
  • Deduplication: AnnouncementService uses course, title, and date to detect duplicates and updates content if changed.
  • Sorting: Announcements are ordered by fetched_at to show most recent entries first.

Notification triggering logic#

  • Trigger condition: New announcements detected during fetch_and_cache for subscribed courses.
  • Storage: Notification records are created linking user, subscription, and announcement.
  • Delivery: NotificationChannelService manages channels; future work will integrate Telegram and Email dispatch.

Dependency analysis#

Layers and who owns what:

  • AnnouncementService depends on Settings and SwayamService
  • SwayamService depends on Settings and the Swayam scraper
  • API routers depend on services via dependency injection
  • Models define relationships and are consumed by services and routers

Performance considerations#

  • Database efficiency: Use of get_or_none with composite filters minimizes unnecessary writes and uses database indexing on course, title, and date.
  • Caching: Cache TTL controls frequency of external scraping; tune Settings.cache_ttl_minutes to balance freshness and cost.
  • Pagination: For large datasets, consider adding pagination to announcement listing endpoints.
  • Asynchronous I/O: SwayamService and AnnouncementService use async patterns to improve throughput.

Troubleshooting guide#

Common issues and resolutions:

  • Course not found: The announcements endpoint raises a 404 if the course code does not exist. Verify the course code and ensure it exists in the Course model.
  • Empty or stale announcements: Confirm that SwayamService scraping is functioning and that cache_ttl_minutes is set appropriately.
  • Authentication errors: Ensure requests include proper authentication as required by require_auth decorators on API endpoints.
  • Database connectivity: Verify database URL in Settings.database_url and that migrations have been applied.

Conclusion#

Scrape, store, list. Wire Telegram or email when you have a worker; until then the inbox is the delivery surface.

Appendices#

API definitions#

  • GET /courses/{course_code}/announcements

  • Description: Returns cached announcements for a course after refreshing from Swayam

  • Authentication: Required

  • Response: List of AnnouncementResponse

  • GET /users/{user_id}/subscriptions

  • Description: Lists a user’s course subscriptions

  • Authentication: Required

  • Response: List of SubscriptionResponse

  • GET /users/{user_id}/notifications

  • Description: Lists notification history for a user

  • Authentication: Required

  • Response: List of NotificationResponse

  • GET /users/me

  • Description: Returns the current authenticated user

  • Authentication: Required

  • Response: UserResponse